﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.DomainLayer;


using HA.MT3DMS.FileLayer;
using HA.ModFlow.Infrastructure;

namespace HA.MT3DMS.DomainLayer
{

    /// <summary>
    /// 基础移动包
    /// </summary>
    [Serializable]
    public class BasicTransport
    {

        public BasicTransport(Units modflowUnits)
        {


            this._stressPeriod = new MTStressPeriodCollecion();

            this._speciesCollecion = new MTSpeciesCollecion(1,1,1);

            this._outputControl = new MTOutputControl();

            this._modelOption = new MTModelOption(modflowUnits);

            _grid = new MTGrid(1,1,1);






            //需要从modflow初始化相关的数据



        }


        double _cINACT=-999;

        public double CINACT
        {
            get { return _cINACT; }
            set { _cINACT = value; }
        }

        double _tHKMIN=0.01;
        /// <summary>
        /// 最小饱和浓度
        /// </summary>
        public double THKMIN
        {
            get { return _tHKMIN; }
            set { _tHKMIN = value; }
        }

        MTGrid _grid;

        public MTGrid Grid
        {
            get { return _grid; }
           
        }

        private bool _htopEqualsTop = true ;
        /// <summary>
        /// MT3D顶板海拔等于MODFLOW的顶板海拔
        /// </summary>
        public bool HtopEqualsTop
        {
            get { return _htopEqualsTop; }
            set { _htopEqualsTop = value; }
        }
        private string _title1 = "MT3D_1";
        /// <summary>
        /// 标题1
        /// </summary>
        public string Title1
        {
            get { return _title1; }
            set { _title1 = value; }
        }
        private string _title2 = "MT3D_2";
        /// <summary>
        /// 标题2
        /// </summary>
        public string Title2
        {
            get { return _title2; }
            set { _title2 = value; }
        }

        MTSpeciesCollecion _speciesCollecion;

        public MTSpeciesCollecion SpeciesCollecion
        {
            get { return _speciesCollecion; }
           
        }


        MTOutputControl _outputControl;

        public MTOutputControl OutputControl
        {
            get { return _outputControl; }
          
        }

        MTStressPeriodCollecion _stressPeriod;

        public MTStressPeriodCollecion StressPeriod
        {
            get { return _stressPeriod; }
           
        }

        MTModelOption _modelOption;

        public MTModelOption ModelOption
        {
            get { return _modelOption; }
        }

        #region 公共函数

        public void ReadModflowSetup(ModFlowData mf)
        {


            //读取对应的网格设置

            GridData gd = mf.GridData;

            this._grid.ResetGrid(gd.RowsCount,gd.ColsCount,gd.LayersCount,gd.RowCoords,gd.ColCoords);

            this._grid.SetElevations(mf.GridData.Elevations);

           




            this.SpeciesCollecion.ResetGrid(gd.RowsCount,gd.ColsCount,gd.LayersCount);

            //去读应力期设置

            List<MTStressPeriod> spList = new List<MTStressPeriod>();

            foreach (StressPeriod item in mf.StressPeriods.InnerList)
            {
                MTStressPeriod sp = new MTStressPeriod(item.PERLEN,item.NSTP);

                spList.Add(sp);
                


                
            }


            this._stressPeriod.ResetPeriods(spList);


            HA.ModFlow.Infrastructure.CellCenterDataSet3d ibound = mf.GridData.GetIBoundDs();

        
            ///用于把MODFLOW的边界Ibound值转换为MT3D的边界Ibound,
            ///如果MODFLOW的边界内的一个单元值为-1,转换为MT3D的边界单元为1它其不变
            int row=ibound .Datas.GetLength(0);
            int col=ibound.Datas .GetLength(1);
            int layer=ibound.Datas.GetLength(2);
          
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j <col; j++)
                {
                    for (int k = 0; k < layer; k++)
                    {
                        if (ibound.Datas[i, j, k] == -1)
                        {
                            ibound.Datas[i, j, k] = 1;
                        }                       
                    }
                }
            }

            this._grid.SetICBoundDS(ibound);
            //========================================================
        }


        public BasicTransportPack ToPack()
        {
            BasicTransportPack pack = new BasicTransportPack();
            pack.NLAY = this._grid.Nlayers;
            pack.NROW = this._grid.Nrows;

            pack.NCOL = this._grid.Ncols;

            pack.NPER = this._stressPeriod.Periods.Count;

            pack.NCOMP = this._speciesCollecion.Species.Count;

            pack.MCOMP = this._speciesCollecion.MobileCount;

            switch (this._modelOption.Units.Time)
            {
                case TIME.DAY:
                    pack.TUNIT = "DAY";
                    break;
                case TIME.HOUR:
                    pack.TUNIT = "HOUR";
                    break;
                case TIME.MINUTE: 
                    pack.TUNIT = "MINUTE";
                    break;
                case TIME.SECOND:
                    pack.TUNIT = "SECOND";
                    break;
                case TIME.YEAR:
                    pack.TUNIT = "YEAR";
                    break;
            }

            switch (this._modelOption.Units.Length)
            {
                case LENGTH.M:
                    pack.LUNIT = "M";
                    break;
                case LENGTH.CM:
                    pack.LUNIT = "CM";
                    break;
                case LENGTH.FT:
                    pack.LUNIT = "FT";
                    break;
            }

            switch (this._modelOption.Units.Mass)
            {
                case MASS.KG: pack.MUNIT = "KG";
                    break;
                case MASS.G: pack.MUNIT = "G";
                    break;
                case MASS.MG: pack.MUNIT = "MG";
                    break;
                case MASS.SLUG: pack.MUNIT = "SLUG";
                    break;
            }


            //List<int> layerCon=new List<int> ();

            foreach (MTGridLayer  layer in this._grid.Layers)
	        {
                pack.LAYCON.Add(layer.LayerCon);

                pack.DZ.Add(layer.DZ);

                pack.PRSITY.Add(layer.Porosity);

                pack.ICBUND.Add(layer.Icbund);



	        }


            pack.DELR.AddRange(this._grid.GetDelR());

            pack.DELC.AddRange(this._grid.GetDelC());

            //现在还未最终确定，先这样默认的走数据，
            pack.HTOP = this._grid.GetTopH();




            foreach (MTSpecies item in this._speciesCollecion.Species)
            {
                foreach (double[,] d in item.InitConc)
                {

                    pack.SCONC.Add(d);

                    
                }
               
               
                
            }


            pack.CINACT = this.CINACT;


            pack.THKMIN = this.THKMIN;


            //输出控制
            switch (this.OutputControl.CN)
            {
                case PrintType.WrapForm: pack.IFMTCN = 1; break;
                case PrintType.NotPrint: pack.IFMTCN = 0; break;
                case PrintType.StripForm: pack.IFMTCN = -1; break;
            }

            switch (this.OutputControl.NP)
            {
                case PrintType.WrapForm: pack.IFMTNP = 1; break;
                case PrintType.NotPrint: pack.IFMTNP = 0; break;
                case PrintType.StripForm: pack.IFMTNP = -1; break;
            }

            switch (this.OutputControl.RF)
            {
                case PrintType.WrapForm: pack.IFMTRF = 1; break;
                case PrintType.NotPrint: pack.IFMTRF = 0; break;
                case PrintType.StripForm: pack.IFMTRF = -1; break;
            }

            switch (this.OutputControl.DP)
            {
                case PrintType.WrapForm: pack.IFMTDP = 1; break;
                case PrintType.NotPrint: pack.IFMTDP = 0; break;
                case PrintType.StripForm: pack.IFMTDP = -1; break;
            }

            if (this.OutputControl.IsSavUcn)
            {
                pack.SAVUCN = "T";
            }
            else
            {
                pack.SAVUCN = "F";
            }




            switch (this._outputControl.StepsType)
            {
                case TimeStepType.SpecifiedTimes:

                    pack.NPRS = this._outputControl.Timesteps.Count;

                    break;
                case TimeStepType.EndSimulation:
                    pack.NPRS = 0;

                    break;
                case TimeStepType.SpecifiedInterval:

                    pack.NPRS =0- this._outputControl.Interval;

                    break;
                default:
                    break;
            }


            if (pack.NPRS>0)
            {
                foreach (double item in this._outputControl.Timesteps)
                {

                    pack.TIMPRS.Add(item);

                    
                }

               
                
            }
         

           


            //观察者包
            pack.NOBS = 0;
            pack.NPROBS = 0;


           // pack.KIJOBS

            pack.NPRMAS = 0;

            if (this.OutputControl.IsSavMass)
            {
                pack.CHKMAS = "T";
            }
            else
            {
                pack.CHKMAS = "F";
            }

            //输入应力期相关

            foreach (MTStressPeriod item in this._stressPeriod.Periods)
            {
                FStressPeriod sp = new FStressPeriod(item.PERLEN,item.NSTP,item.TSMULT);

                sp.DT0 = item.TransStepSize;
                sp.MXSTRN = item.MaxTransSteps;
                sp.TTSMULT = item.TransStepMultiplier;
                sp.TTSMAX = item.MaxTransStepSize;
                pack.Periods.Add(sp);



            }



          
            /// 只在特定情况输入 tsmult<=0
           /// pack.TSLNGH.Add 
           /// 

            //pack.DT0 = 1;

            //pack.MXSTRN = 1000;

            //pack.TTSMULT = 1;

            //pack.TTSMAX = 3.5;


           





            return pack;
        }

        #endregion


    }
}
